# Написать обработчик для прерываний по таймеру и исключений. Для прерываний по таймеру обработчик должен выводить тип таймера (из регистра utval),
# а для исключений — причину исключения (из регистра ucause).

.globl	main
.text
main:	la      a0 handler	# Сохранение адреса обработчика исключения в utvec
        csrw    a0 utvec
        csrwi   uie 0x10	# Разрешить обработку прерываний от таймера (четвертый бит CSR uie должен быть установлен в 1)
        csrwi   ustatus 1	# Разрешить обработку исключений (бит 0 в регистре ustatus)

        			# А здесь должна быть основная программа
        
	li	a7 10
	ecall

.data
h_a0:   .space  4
h_a7:   .space  4

.text
handler:
	csrw	t0 uscratch
	sw      a0 h_a0 t0      # Сохраним a0
        sw      a7 h_a7 t0      # Сохраним a7
	
	csrr	a0 ucause
	bltz	a0 interrupt
	
	li      a7 34           # Если исключение выведем причину
        ecall
        li      a0 '\n'
        li      a7 11
        ecall
	csrr    t0 uepc         # Адрес прерванной инструкции        
        addi    t0 t0 4         # Адрес следующей инструкции
        csrw    t0 uepc         # Запишем его
	b	exit

interrupt:
	csrr	a0 utval	# Если прерывание выведем тип таймера	
	li      a7 34
        ecall
        li      a0 '\n'
        li      a7 11
        ecall
       
exit:   lw      a0 h_a0         # Восстановим a0
        lw      a7 h_a7         # Восстановим a7
	csrr    t0 uscratch     # восстановим t0
        uret
